package cn.yitun.chat.yitunserverimapicore.business.personal.service.impl;

import cn.yitun.chat.yituncommonmessage.ExceptionEnum;
import cn.yitun.chat.yituncommonmessage.Info;
import cn.yitun.chat.yituncommonmessage.impl.HeadImpl;
import cn.yitun.chat.yituncommonmessage.result.ResultMessage;
import cn.yitun.chat.yituncommonutil.YitunMD5Util;
import cn.yitun.chat.yituncommonutil.YitunRegexUtil;
import cn.yitun.chat.yituncommonutil.YitunStringUtil;
import cn.yitun.chat.yitunservercommonlib.converter.dto2po.user.UserDto2PoConverter;
import cn.yitun.chat.yitunservercommonlib.converter.dto2vo.user.UserDto2VoConverter;
import cn.yitun.chat.yitunservercommonlib.crud.yitun.CrudServiceImpl;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.system.user.UserDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.system.user.UserExtendsDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.userchat.SecurityQuestionDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.userchat.UserHeadDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.user.UserExtendsInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.user.UserInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.user.UserExtendsVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.user.UserVo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.userchat.UserHeadVo;
import cn.yitun.chat.yitunservercommonlib.enums.system.UserHeadTypeEnums;
import cn.yitun.chat.yitunservercommonlib.util.R;
import cn.yitun.chat.yitunservercommonlib.util.cache.TokenTemporaryCache;
import cn.yitun.chat.yitunservercommonlib.util.codec.IdGen;
import cn.yitun.chat.yitunservercommonmessage.data.user.LoginDto;
import cn.yitun.chat.yitunserverimapicore.business.personal.service.PersonalService;
import cn.yitun.chat.yitunserverimbase.dao.system.UserDao;
import cn.yitun.chat.yitunserverimbase.dao.system.UserExtendsDao;
import cn.yitun.chat.yitunserverimbase.dao.userchat.UserHeadDao;
import cn.yitun.chat.yitunserverimbase.dao.userchat.UserNumberDao;
import cn.yitun.chat.yitunserverimcore.bridge.main.business.user.store.UserStore;
import cn.yitun.chat.yitunserverimcore.general.main.biz.personal.manager.PersonalManager;
import cn.yitun.chat.yitunserverimcore.general.main.biz.userchat.manager.SecurityQuestionManager;
import cn.yitun.chat.yitunserverimcore.general.main.biz.userchat.manager.UserManager;
import cn.yitun.chat.yitunserverimcore.general.main.push.user.PersonalPush;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.List;

/**
 * 
 * Date 2019-01-20 09:40:46<br>
 * Description 个人业务处理service
 * 
 * @author yitun
 * @since 1.0.0
 */
@Service
public class PersonalServiceImpl
		extends CrudServiceImpl<UserExtendsDao, UserExtendsDto, UserExtendsInfo, UserExtendsVo>
		implements PersonalService{

	@Resource
	private UserDao userDAO;
	@Resource
	private UserHeadDao userHeadDAO;
	@Resource
	private UserNumberDao numberDAO;
	@Resource
	private UserStore userStore;
	@Resource
	private PersonalPush personalPush;
	@Resource
	private UserManager userManager;
	@Resource
	private SecurityQuestionManager securityQuestionManager;
	@Resource
	private PersonalManager personalManager;
	@Resource
	private TokenTemporaryCache tokenTemporaryCache;


	/**
	 * Description 登录 <br>
	 * Date 2019-04-30 09:56:08<br>
	 * @param loginData
	 * @return ResultMessage
	 * @since 1.0.0
	 */
	@Transactional(readOnly = true)
	public ResultMessage login(LoginDto loginData) {
		ResultMessage message = new ResultMessage();

		if (loginData == null)
			return ResultMessage.error(Info.InfoType.WARNING.value(), ExceptionEnum.LOSE_FILED);
		if (YitunStringUtil.isEmpty(loginData.getAccount())
				|| YitunStringUtil.isEmpty(loginData.getPassword()))
			return ResultMessage.error(Info.InfoType.WARNING.value(), ExceptionEnum.LOSE_FILED);

		String account = loginData.getAccount();
		account = account.replace(" ", "").replace("'", "");
		UserInfo user = null;
		if (YitunRegexUtil.isEmail(account)) {
			user = userDAO.getUserByEmail(account);
		} else if (YitunRegexUtil.isMobile(account)) {
			user = userDAO.getUserByMobile(account);
		} else {
			user = userDAO.getUserByAccount(account);
		}
		if (user == null)
			return ResultMessage.error(Info.InfoType.WARNING.value(), ExceptionEnum.ACCOUNT_NOT_EXISTS);

		if (! YitunMD5Util.md5L32(loginData.getPassword()).equals(user.getPassword()))
			return ResultMessage.error(Info.InfoType.WARNING.value(), ExceptionEnum.USERNAME_OR_PASSWORD_ERROR);

		String token = userManager.createJwtToken(UserDto2PoConverter.INSTANCE.do2dto(user));
		tokenTemporaryCache.put(token, user.getId());
		message.bodyPut("token", token);
		message.bodyPut("user", userDAO.getVO(user.getId()));

		return message;
	}

	/**
	 * 注册
	 * 
	 * @param user
	 * @return
	 */
	@Transactional
	public Info register(UserDto user, List<SecurityQuestionDto> list) {
		Info info = userManager.add(user);
		if (info.isSuccess()) {
			securityQuestionManager.save(list, user.getId());
		}
		return info;
	}

	/**
	 * Date 2019-01-20 11:21:08<br>
	 * Description 修改用户信息
	 * @author yitun
	 * @param user
	 * @return
	 * @since 1.0.0
	 */
	@Transactional
	public Info updatePersonal(UserDto user) {
		Info info = userManager.updatePersonal(user);
		if (info.isSuccess()) {
			personalPush.pushUpdate(IdGen.getNumber(), user.getId());
		}
		return info;
	}

	/**
	 * Date 2019-01-20 11:27:30<br>
	 * Description 修改密码
	 * @author yitun
	 * @param userId
	 * @param oldPassword
	 * @param newPassword
	 * @return
	 * @since 1.0.0
	 */
	@Transactional
	public ResultMessage updatePassword(Long userId, String oldPassword, String newPassword) {
		ResultMessage message = new ResultMessage();
		try {
			UserInfo user = userDAO.get(userId);
			if (user.getPassword().equals(YitunMD5Util.md5L32(oldPassword))) {
				boolean mark = personalManager.updatePassword(userId, YitunMD5Util.md5L32(newPassword));
				if (!mark) {
					message.addWarning(ExceptionEnum.DO_FAIL);
				}
			} else {
				message.addWarning(ExceptionEnum.USER_PASSWORD_FALSE);
			}
		} catch (Exception e) {
			e.printStackTrace();
			message.addWarning(ExceptionEnum.DO_FAIL);
		}
		return message;
	}

	/**
	 * Date 2019-01-20 11:21:48<br>
	 * Description 用户上传图像
	 * @author yitun
	 * @param userHead
	 * @return
	 * @since 1.0.0
	 */
	@Transactional
	public ResultMessage uploadHead(UserHeadDto userHead) {
		ResultMessage message = new ResultMessage();
		try {

			if (userHeadDAO.count(R.param("userId", userHead.getUserId())) > 0)
				userHeadDAO.removeByUserId(userHead.getUserId());

			userHead.setCreateBy(userHead.getUserId());
			userHead.setUpdateBy(userHead.getUserId());
			userHeadDAO.save(userHead);

			Long headId = userHead.getHeadId();
			Long userId = userHead.getUserId();
			String type = userHead.getType();
			String url = userHead.getUrl();
			// 用户自定义头像，则清除系统头像
			if (UserHeadTypeEnums.TYPE_CUSTOM.getType().equals(type)) {
				userDAO.updateAvatar(userId, url);
			} else {
				userDAO.updateHead(userId, headId);
				userDAO.updateAvatar(userId, "");
			}
			message.bodyPut("head", userHead);

			personalPush.pushUpdateHead(IdGen.getNumber(), userId);
			userManager.updateHead(userId);
		} catch (Exception e) {
			message.addWarning(ExceptionEnum.DO_FAIL);
		}
		return message;
	}

	/**
	 * Date 2019-01-20 11:26:52<br>
	 * Description 修改个性签名
	 * @author yitun
	 * @param userId
	 * @param signature
	 * @return
	 * @since 1.0.0
	 */
	@Transactional
	public boolean updateSignature(Long userId, String signature) {
		UserDto userDto = new UserDto();
		userDto.setUserId(userId);
		userDto.setSignature(signature);
		return userDAO.updatePersonal(userDto) > 0;
	}

//	public void updateStatus(Long userId, String status) {
//		userStore.putStatus(userId, status);
//		userManager.updateStatus(userId, status);
//		personalPush.pushUpdateStatus(IdGen.getNumber(), userId, status);
//	}

	/**
	 * Date 2019-01-20 11:27:05<br>
	 * Description 修改在线状态
	 * @author yitun
	 * @param userId
	 * @param chatOnline 在线状态
	 * @since 1.0.0
	 */
	@Override
	public void updateChatOnlineStatus(Long userId, String chatOnline) {
		userStore.putStatus(userId, chatOnline);
		userManager.updateChatOnlineStatus(userId, chatOnline);
		personalPush.pushUpdateChatOnlineStatus(IdGen.getNumber(), userId, chatOnline);
	}

	public UserHeadVo getUserHeadByUserId(Long userId) {
		UserHeadVo head = userHeadDAO.getLastByUserId(userId);
		return head;
	}
}
